package com.eagle.roomsearch.util;

import com.alibaba.fastjson.JSON;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.DefaultHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.BasicHttpClientConnectionManager;
import org.apache.http.util.EntityUtils;

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.URI;
import java.security.KeyStore;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Iterator;
import java.util.Map;

/**
 * request请求工具类
 *
 * @author SQG
 * @version ╮(╯▽╰)╭
 * @date 2018/1/9
 * @time 14:37
 * @modify by Jetvin
 */
public class RequestUtil {

    /**
     * 获取真实IP
     *
     * @author SQG
     * @date 2018/1/9
     * @time 14:38
     * @version ╮(╯▽╰)╭
     * @modify by
     */
    public static String getIp(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }

    /**
     * 获取MAC地址
     *
     * @author SQG
     * @date 2018/1/9
     * @time 14:38
     * @version ╮(╯▽╰)╭
     * @modify by
     */
    public static String getMAC(String ip) {
        String str = null;
        String macAddress = null;
        try {
            Process p = Runtime.getRuntime().exec(" nbtstat -A " + ip);
            InputStreamReader ir = new InputStreamReader(p.getInputStream(), "UTF-8");
            LineNumberReader input = new LineNumberReader(ir);
            for (; true; ) {
                str = input.readLine();
                System.out.println(str);
                if (str != null) {
                    if (str.indexOf("MAC Address") > 1) {
                        macAddress = str
                                .substring(str.indexOf("MAC Address") + 14);
                        break;
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace(System.out);
            return null;
        }
        return macAddress;
    }

    /**
     * 创建HTTP通信的客户端
     *
     * @param key
     * @return
     * @author Jetvin
     * @date 2017年9月30日
     * @time 下午5:42:22
     * @version ╮(╯▽╰)╭
     */
    private static HttpClient getHttpClient(boolean key) {
        try {
            // 创建SSLContext
            SSLContext sslContext = SSLContext.getInstance("TLS");

            if (key) {
                // 实例化密钥库
                char[] password = {};//TODO 根据需要修改
                FileInputStream instream = new FileInputStream(new File(""));//TODO 根据需要修改
                KeyStore keyStore = KeyStore.getInstance("PKCS12");
                keyStore.load(instream, password);

                // 初始化密钥工厂
                KeyManagerFactory km = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
                km.init(keyStore, password);

                // km 密钥管理器; random 加密随机数; tm 授权证书管理器
                sslContext.init(km.getKeyManagers(), null, new SecureRandom());

            } else {
                // 创建管理授权证书工厂
                X509TrustManager trustManager = new X509TrustManager() {

                    @Override
                    public X509Certificate[] getAcceptedIssuers() {

                        return new X509Certificate[]{};
                    }

                    @Override
                    public void checkServerTrusted(X509Certificate[] chain, String authType)
                            throws CertificateException {
                    }

                    @Override
                    public void checkClientTrusted(X509Certificate[] chain, String authType)
                            throws CertificateException {
                    }
                };

                sslContext.init(null, new TrustManager[]{trustManager}, new SecureRandom());
            }

            // 创建SSLConnectionSocketFactory
            // sslContext SSL套接字协议;
            // supportedProtocols 认证协议;
            // supportedCipherSuites 密码套件;
            // hostnameVerifier主机认证
            SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(
                    sslContext,
                    new String[]{"TLSv1"},
                    null,
                    new DefaultHostnameVerifier());

            // 创建BasicHttpClientConnectionManager
            // socketFactoryRegistry 协议注册;
            // connFactory 请求;
            // schemePortResolver 策略端口;
            // dnsResolver 域名解析
            BasicHttpClientConnectionManager connManager = new BasicHttpClientConnectionManager(
                    RegistryBuilder.<ConnectionSocketFactory>create()
                            .register("http", PlainConnectionSocketFactory.getSocketFactory())
                            .register("https", sslConnectionSocketFactory).build(),
                    null,
                    null,
                    null);

            // 创建HttpClient
            HttpClient httpClient = HttpClientBuilder.create().setConnectionManager(connManager).build();

            return httpClient;
        } catch (Exception e) {

            return null;
        }
    }

    /**
     * 发送POST请求
     *
     * @param url  请求url
     * @param data 参数（xml格式或json格式）
     * @param key  是否使用证书
     * @return
     * @author Jetvin
     * @date 2017年10月1日
     * @time 下午8:52:20
     * @version
     */
    public static String sendPost(String url, String data, boolean key) {
        try {
            // 获取HttpClient
            HttpClient httpClient = getHttpClient(key);

            // 创建HttpPost
            HttpPost httpPost = new HttpPost(url);

            StringEntity postEntity = new StringEntity(data, "UTF-8");
            if (isXml(data)) {
                httpPost.addHeader("Content-Type", "text/xml");
            } else {
                httpPost.addHeader("Content-Type", "application/json");
            }

            httpPost.addHeader("User-Agent", "User-Agent"); // TODO: 加用户代理，要修改
            httpPost.setEntity(postEntity);

            // 创建HttpResponse
            HttpResponse httpResponse = httpClient.execute(httpPost);
            HttpEntity httpEntity = httpResponse.getEntity();

            return EntityUtils.toString(httpEntity, "UTF-8");

        } catch (Exception e) {

            ExceptionUtil.printf(e);
            return null;
        }

    }

    /**
     * 发送POST请求
     *
     * @param url  请求url
     * @param data 参数（Map格式）
     * @param key  是否使用证书
     * @return
     * @author Jetvin
     * @date 2017年9月30日
     * @time 下午4:52:45
     * @version ╮(╯▽╰)╭
     */
    public static String sentPost(String url, Map<String, String> data, boolean key) {

        return sendPost(url, (String) JSON.toJSONString(data), key);
    }

    /**
     * 校验参数格式
     *
     * @param data
     * @return
     * @author Jetvin
     * @date 2017年10月11日
     * @time 上午10:56:05
     * @version ╮(╯▽╰)╭
     */
    private static boolean isXml(String data) {

        if (data.startsWith("<?xml")) {
            return true;
        }

        return false;
    }

    /**
     * 发送GET请求
     *
     * @param url  请求url
     * @param data 参数（Map格式）
     * @return
     * @author Jetvin
     * @date 2017年9月30日
     * @time 下午4:31:53
     * @version ╮(╯▽╰)╭
     */
    public static String sendGet(String url, Map<String, String> data) {
        try {
            // 创建客户端
            HttpClient httpClient = getHttpClient(false);
            // 请求参数设置
            RequestConfig config = RequestConfig.custom().setSocketTimeout(50000).setConnectTimeout(50000)
                    .setConnectionRequestTimeout(50000).build();
            // 创建GET请求
            HttpGet httpGet = new HttpGet();

            // 拼接url
            if (data != null) {
                String params = convertStringParamter(data);
                url = url + "?" + params;
            }

            // 设置参数
            httpGet.setConfig(config);
            httpGet.setURI(new URI(url));


            // 发送请求
            HttpResponse httpResponse = httpClient.execute(httpGet);
            // 获取返回的数据
            HttpEntity entity = httpResponse.getEntity();
            String response = EntityUtils.toString(entity, "utf-8");

            return response;
        } catch (Exception e) {

            ExceptionUtil.printf(e);
        }
        return null;

    }

    /**
     * 请求参数拼接
     *
     * @param parames
     * @return
     * @author Jetvin
     * @date 2017年9月30日
     * @time 下午3:54:23
     * @version ╮(╯▽╰)╭
     */
    public static String convertStringParamter(Map<String, String> parames) {
        StringBuffer parameterBuffer = new StringBuffer();

        // 若参数为空不处理
        if (parames != null) {

            Iterator<String> iterator = parames.keySet().iterator();
            String key = null;
            String value = null;

            while (iterator.hasNext()) {
                // 拼接参数
                key = (String) iterator.next();
                if (parames.get(key) != null) {
                    value = (String) parames.get(key);
                    parameterBuffer.append(key).append("=").append(value);
                }
                // 非末尾处添加 & 连接符
                if (iterator.hasNext()) {
                    parameterBuffer.append("&");
                }
            }
        }

        return parameterBuffer.toString();
    }
}
